package examples;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.namespace.QName;
import javax.xml.transform.stream.StreamSource;
import javax.xml.ws.BindingProvider;

import junit.framework.TestCase;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import com.mu.rai.services.MuApi;
import com.mu.rai.services.MuApi_Service;
import com.mu.rai.services.TemplateContainer;

public abstract class AbstractWSTestCase extends TestCase {

	protected static final Logger logger = Logger.getLogger(AbstractWSTestCase.class);

//	private static final String CERTIFICATE_FILE_NAME = "jssecacerts";

	private final List<Object> objectsToCleanup = new ArrayList<Object>();

	@Override
	public String getName() {
		return super.getName();
	}

	@Override
	public void setUp() throws Exception {
		super.setUp();
		if (StringUtils.isBlank(System.getProperty("javax.net.ssl.trustStore"))) {
			final String fileName = "/Volumes/musecurity/MuStaf/jssecacerts";
			System.setProperty("javax.net.ssl.trustStore", fileName);
			System.setProperty("javax.net.ssl.trustPassword", "changeit");
			// ignore SSL error "HTTPS hostname wrong: should be ..."
			HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
				public boolean verify(String urlHostName, SSLSession session) {
					return urlHostName.equals(session.getPeerHost());
				}
			});
		}
	}

	@Override
	public void tearDown() throws Exception {
		super.tearDown();
		cleanup(getObjectsToCleanup());
	}

	protected void cleanup(final File file) throws IOException {
		if (file.isDirectory()) {
			;
		} else {
			file.delete();
		}
	}

	protected void cleanup(final InputStream stream) throws Exception {
		stream.close();
	}

	protected final void cleanup(final List<Object> objectsToCleanup) throws Exception {
		for (final Object object : objectsToCleanup) {
			try {
				cleanup(object);
			} catch (Exception e) {
				logger.error(e, e);
			}
		}
	}

	protected void cleanup(final Long jobId) throws Exception {
	}

	protected void cleanup(final Object object) throws Exception {
		if (File.class.isInstance(object)) {
			final File file = File.class.cast(object);
			cleanup(file);
		} else if (String.class.isInstance(object)) {
			cleanup(String.class.cast(object));
		} else if (InputStream.class.isInstance(object)) {
			cleanup(InputStream.class.cast(object));
		} else if (OutputStream.class.isInstance(object)) {
			cleanup(OutputStream.class.cast(object));
		} else if (Long.class.isInstance(object)) {
			cleanup(Long.class.cast(object));
		}
	}

	protected void cleanup(final OutputStream stream) throws Exception {
		stream.close();
	}

	protected void cleanup(final String uuid) throws Exception {
	}

	protected final MuApi getApi() {
		try {
			final MuApi store = new MuApi_Service(new URL("http://10.10.5.70:8888/rai/services/mu?wsdl"),
					new QName("http://services.rai.mu.com", "MuApi")).getMuApi();
			setAuthorizationCredentials(store);
			return store;
		} catch (MalformedURLException e) {
			throw new RuntimeException(e);
		}
	}

	protected final List<Object> getObjectsToCleanup() {
		return objectsToCleanup;
	}

	protected final  TemplateContainer parse(final String fileName) throws JAXBException {
		final JAXBContext ctx = JAXBContext.newInstance(new Class<?>[]{TemplateContainer.class}, null);
		final JAXBElement<TemplateContainer> unmarshalledObject = ctx.createUnmarshaller().unmarshal(new StreamSource(getClass().getResourceAsStream(fileName)), TemplateContainer.class);
		final TemplateContainer response = unmarshalledObject.getValue();
		assertNotNull(response);
		assertNotNull(response.getTemplates());
		assertNotNull(response.getTemplates().getSyslogNotifierOrAnalysisOrDosAttack());
		assertFalse(response.getTemplates().getSyslogNotifierOrAnalysisOrDosAttack().isEmpty());
		return response;
	}
	
	protected final void setAuthorizationCredentials(final Object store) {
		if (store instanceof BindingProvider) {
			BindingProvider provider = (BindingProvider) store;
			provider.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "admin");
			provider.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "admin");
		}
	}


}
